package com.griddroid.activities;

import com.griddroid.configuration.GridClientConfig;
import com.griddroid.configuration.GridConfig;
import com.griddroid.nodes.GridClient;
import com.griddroid.works.WorkRequest;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

/**
 * This activity is the one that runs on the client machine. It also includes a
 * {@link GridClient GridClient} to handle the connections and the messages from
 * and to the Grid, a handler, which is responsible for refreshing the GUI, and
 * a custom view. The latter creates a GUI suitable for a scientific calculator.
 * <p>
 * When the user inputs a command in the textbox, that command is translated
 * (using {@link GridClient#workRequestFromString(String)
 * workRequestFromString(String)}) to a {@link WorkRequest WorkRequest}. The
 * contained gridclient sends that work request to the server and waits for any
 * results. At that time, through the handler, the view is updated.
 * 
 * @author Charalampos Mavroforakis
 * @author Thomas Ailianos
 * @author Michail Michailidis
 * 
 */
public class Client extends Activity implements Runnable
{
	LogTextBox tv;
	GridClient client;

	
	/**
	 * Called when the activity is first created. It starts the main thread,
	 * sets the {@link OnClickListener OnClickListener} of the button and a key
	 * listener for the BACK button of the mobile device. This will terminate
	 * the client
	 */
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		tv = new LogTextBox(this);
		setContentView(R.layout.client);
		Thread c_thread = new Thread(this);
		c_thread.start();
		final Button button = (Button) findViewById(R.id.bt_calc);
		button.setOnClickListener(new View.OnClickListener()
		{
			public void onClick(View v)
			{
				// Submit job on click
				if (client != null)
				{
					String expr = ((TextView) findViewById(R.id.txtbox_input)).getText().toString();
					if (expr != "" && expr != null)
					{
						client.workRequestFromString(expr);
						TextView tx_output = (TextView) findViewById(R.id.txt_output);
						tx_output.setText("");
					}
				}

			}
		});
		
		final TransparentPanel ts = (TransparentPanel)findViewById(R.id.transparent_panel);
		ts.setOnClickListener(new View.OnClickListener()
		{
			public void onClick(View v)
			{
				ts.setFocusable(false);
				ts.setFocusableInTouchMode(false);
				ts.setVisibility(View.INVISIBLE);
				ts.setVisibility(View.GONE);
				ts.invalidate();
				final AbsoluteLayout al = (AbsoluteLayout)Client.this.findViewById(R.id.AbsoluteLayout);
				al.invalidate();
			}
		});
	}

	/**
	 * This is the handler responsible for any messages from the included grid
	 * client.
	 */
	public Handler messageHandler = new Handler()
	{

		/**
		 * It has been overridden, so that it will handle the custom messages
		 * accordingly. Through this method, the handler will start or stop the
		 * view's {@link ProgressBar ProgressBar}, will print messages on the
		 * view (errors or results) or change the input text
		 * 
		 * @param msg
		 *            a message from the GridClient. Its {@link Message#what
		 *            'what' attribute} is set according to the
		 *            {@link GridClientConfig GridClient configuration},
		 *            denoting the purpose of the message
		 */
		@Override
		public void handleMessage(Message msg)
		{
			if (msg.what == GridConfig.UPDATE_TEXTVIEW)
			{
				tv.append((String) msg.obj);
			}
			else if (msg.what == GridClientConfig.START_WAITING)
			{
				ProgressBar pb = (ProgressBar) findViewById(R.id.prg_progress);
				pb.setVisibility(View.VISIBLE);
				// start progress
			}
			else if (msg.what == GridClientConfig.STOP_WAITING)
			{
				// stop progress
				ProgressBar pb = (ProgressBar) findViewById(R.id.prg_progress);
				pb.setVisibility(View.INVISIBLE);
			}
			else if (msg.what == GridClientConfig.WORK_RESPONSE)
			{
				TextView tx_output = (TextView) findViewById(R.id.txt_output);
				Double res = (Double) msg.obj;
				tx_output.setText(res.toString());
			}
			else if (msg.what == GridClientConfig.ERROR)
			{
				TextView tx_output = (TextView) findViewById(R.id.txt_output);
				String error = (String) msg.obj;
				tx_output.setText(error);
			}
			else if (msg.what == GridConfig.CLOSE)
			{
				finish();
			}
		}
	};

	/**
	 * Initializes the GridClient, sets its handler and finally starts the
	 * activity
	 */
	@Override
	public void run()
	{
		client = new GridClient(messageHandler);
		client.setHandler(messageHandler);
		client.start();
	}
	
	/**
	 * Overridden method to handle the press of the Back Button on the mobile
	 * device. It will shutdown the client.
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent ev)
	{
		if (keyCode == KeyEvent.KEYCODE_BACK)
		{
			if (client != null)
			{
				client.sendEndSessionMessage();
				client = null;
			}
			return true;
		}
		return false;
	}
}
